package com.lipei.vrp.ui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

public class BatchDialog extends JDialog {

	private class Job implements Callable<Integer> {
		private String line;

		public Job(String line) {
			this.line = line;
		}

		@Override
		public Integer call() throws Exception {

			textArea.append("start:" + line + "\r\n");

			ProcessBuilder builder = buildPro();

			File outfile = new File(UUID.randomUUID().toString());
			builder.redirectOutput(outfile);

			Process pro = builder.start();
			pro.waitFor();

			synchronized (resultfile) {
				resultfile.write(line);
				resultfile.write("\r\n");
				resultfile.write("start\r\n");
				resultfile.write("\r\n");
				BufferedReader input = new BufferedReader(
						new InputStreamReader(
								FileUtils.openInputStream(outfile)));
				IOUtils.copy(input, resultfile);
				resultfile.write(line);
				resultfile.write("  end\r\n");
				resultfile.write("\r\n");
				resultfile.write("\r\n");
				resultfile.flush();
				input.close();
			}

			FileUtils.deleteQuietly(outfile);
			textArea.append("ended:" + line + "\r\n");
			return null;
		}

		private ProcessBuilder buildPro() {

			String[] split = line.split(" ");
			ArrayList<String> list = new ArrayList<String>();
			list.add("java");
			// list.add("-Xdebug");
			// list.add("-Xrunjdwp:server=y,transport=dt_socket,address=8002,suspend=y");
			list.add("-jar");
			list.add("C:\\Users\\lipei\\Desktop\\vrp\\vrprun.jar");
			list.addAll(Arrays.asList(split));
			return new ProcessBuilder(list);
		}
	}

	private final JPanel contentPanel = new JPanel();
	private JTextField batchText;
	private JTextField resultText;
	private JTextField lineText;
	private ArrayList<String> lines;
	private JSpinner spinner;
	private ThreadPoolExecutor extor;
	private JSpinner spinnerThread;
	private BufferedWriter resultfile;
	private JTextArea textArea;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		try {
			BatchDialog dialog = new BatchDialog();
			dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
			dialog.setVisible(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Create the dialog.
	 */
	public BatchDialog() {
		setResizable(false);
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				if (resultfile != null) {
					try {
						resultfile.close();
						resultfile = null;
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}
		});
		setBounds(100, 100, 693, 431);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(null);

		JLabel lblNewLabel = new JLabel("Batch File:");
		lblNewLabel.setBounds(0, 27, 75, 30);
		contentPanel.add(lblNewLabel);

		batchText = new JTextField();
		batchText.setEditable(false);
		batchText.setBounds(85, 32, 351, 20);
		contentPanel.add(batchText);
		batchText.setColumns(10);

		JButton browseBatchButton = new JButton("Browse...");
		browseBatchButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser chooser = new JFileChooser();
				chooser.setFileFilter(new FileNameExtensionFilter("bat file",
						"bat"));
				if (!StringUtils.isEmpty(batchText.getText())) {
					chooser.setCurrentDirectory(new File(batchText.getText())
							.getParentFile());
				}
				if (chooser.showOpenDialog(getContentPane()) != JFileChooser.APPROVE_OPTION) {
					return;
				}
				File file = chooser.getSelectedFile();
				batchText.setText(file.getAbsolutePath());

				initState();
			}
		});
		browseBatchButton.setBounds(446, 31, 89, 23);
		contentPanel.add(browseBatchButton);

		JLabel lblNewLabel_1 = new JLabel("Result File:");
		lblNewLabel_1.setBounds(0, 68, 75, 14);
		contentPanel.add(lblNewLabel_1);

		resultText = new JTextField();
		resultText.setBounds(85, 65, 351, 20);
		contentPanel.add(resultText);
		resultText.setColumns(10);

		JButton browseResultButton = new JButton("Browse...");
		browseResultButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser chooser = new JFileChooser();
				chooser.setFileFilter(new FileNameExtensionFilter("txt file",
						"txt"));
				if (!StringUtils.isEmpty(resultText.getText())) {
					chooser.setCurrentDirectory(new File(resultText.getText())
							.getParentFile());
				}
				if (chooser.showSaveDialog(getContentPane()) != JFileChooser.APPROVE_OPTION) {
					return;
				}
				File file = chooser.getSelectedFile();
				resultText.setText(file.getAbsolutePath());
			}
		});
		browseResultButton.setBounds(446, 65, 89, 23);
		contentPanel.add(browseResultButton);

		JButton startButton = new JButton("Start");
		startButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				start();
			}
		});
		startButton.setBounds(85, 121, 89, 23);
		contentPanel.add(startButton);

		JButton tryButton = new JButton("Try End");
		tryButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				extor.shutdown();
				textArea.append("try end \r\n");
				new Thread(new Runnable() {

					@Override
					public void run() {
						try {
							extor.awaitTermination(0, TimeUnit.MILLISECONDS);
							textArea.append("job end \r\n");
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}).start();

			}
		});
		tryButton.setBounds(184, 121, 89, 23);
		contentPanel.add(tryButton);

		JButton forceButton = new JButton("Force End");
		forceButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

			}
		});
		forceButton.setBounds(283, 121, 89, 23);
		contentPanel.add(forceButton);

		JLabel resultLable = new JLabel("");
		resultLable.setBounds(85, 130, 287, 14);
		contentPanel.add(resultLable);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane
				.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		scrollPane
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		scrollPane.setBounds(85, 155, 351, 140);
		contentPanel.add(scrollPane);

		textArea = new JTextArea();
		scrollPane.setViewportView(textArea);
		textArea.setEditable(false);

		JLabel lblNewLabel_2 = new JLabel("Begin Line:");
		lblNewLabel_2.setBounds(0, 93, 75, 14);
		contentPanel.add(lblNewLabel_2);

		spinner = new JSpinner();
		spinner.setBounds(85, 90, 89, 20);
		contentPanel.add(spinner);

		lineText = new JTextField();
		lineText.setEditable(false);
		lineText.setBounds(286, 90, 86, 20);
		contentPanel.add(lineText);
		lineText.setColumns(10);

		JLabel lblNewLabel_3 = new JLabel("Total Line:");
		lblNewLabel_3.setBounds(184, 96, 89, 14);
		contentPanel.add(lblNewLabel_3);

		JButton readButton = new JButton("Read");
		readButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			}
		});
		readButton.setBounds(545, 31, 89, 23);
		contentPanel.add(readButton);

		JLabel lblNewLabel_4 = new JLabel("Thread:");
		lblNewLabel_4.setBounds(410, 96, 46, 14);
		contentPanel.add(lblNewLabel_4);

		spinnerThread = new JSpinner();
		spinnerThread.setModel(new SpinnerNumberModel(1, null, 8, 1));
		spinnerThread.setBounds(456, 90, 46, 20);
		contentPanel.add(spinnerThread);
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
		}
	}

	protected void start() {
		startButton();
		try {
			resultfile = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(resultText.getText())));
			Thread thread = new Thread(new Runnable() {

				@Override
				public void run() {
					Integer threadnum = (Integer) spinnerThread.getValue();

					LinkedBlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<Runnable>();
					extor = new ThreadPoolExecutor(threadnum, threadnum, 0,
							TimeUnit.MILLISECONDS, workQueue);

					ArrayList<Callable<Integer>> list = new ArrayList<Callable<Integer>>();
					for (String line : lines) {
						list.add(new Job(line));
					}

					try {
						extor.invokeAll(list);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}
			});
			thread.start();

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	protected void initState() {
		try {
			File batchfile = new File(batchText.getText());
			if (!batchfile.exists()) {
				lineText.setText("");
				JOptionPane.showMessageDialog(getParent(),
						"batch file can't be opened");
				return;
			}

			if (StringUtils.isEmpty(resultText.getText())) {
				resultText.setText(batchfile.getAbsolutePath() + ".txt");
			}

			BufferedReader reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(batchfile)));
			lines = new ArrayList<String>();
			while (true) {
				String line = reader.readLine();
				if (line == null) {
					break;
				}
				if (StringUtils.isEmpty(line)) {
					continue;
				}
				lines.add(line);
			}

			spinner.setModel(new SpinnerNumberModel(new Integer(1),
					new Integer(1), new Integer(lines.isEmpty() ? 1 : lines
							.size()), new Integer(1)));
			lineText.setText((lines.isEmpty() ? "" : lines.size()).toString());

			initButton();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void startButton() {
		// TODO Auto-generated method stub

	}

	private void initButton() {

	}
}
